﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace DataAccess.Repository
{
	public class MailRepository : IMailRepository, IDisposable
	{
		private KPIDbContext _KPIDbContext = new KPIDbContext();

		private Models.MailMessage GetMailMessageFromReader(System.Data.Common.DbDataReader rd)
		{
			Models.MailMessage result = null;

			if(rd != null)
			{
				var item = new Models.MailMessage();
				for(var i = 0; i < rd.FieldCount; i++)
				{
					switch(rd.GetName(i))
					{
						case "MailID":
							{
								item.MailID = Convert.ToInt32(rd[rd.GetName(i)]);
							}
							break;
						case "MailSubject":
							{
								item.MailSubject = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "MailContent":
							{
								item.MailContent = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "MailFrom":
							{
								item.MailFrom = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "MailSendTime":
							{
								if(rd[rd.GetName(i)] != DBNull.Value)
								{
									item.MailSendTime = Convert.ToDateTime(rd[rd.GetName(i)]);
								}
							}
							break;
						case "MailAttFile":
							{
								item.MailAttFile = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
							}
							break;
						case "MailIsDelete":
							{
								item.MailIsDelete = Convert.ToInt32(rd[rd.GetName(i)]);
							}
							break;
						case "Reciever":
							{
								if(item.ListMailReciever == null)
								{
									item.ListMailReciever = new List<Models.MailReciever>();
									item.ListMailReciever.Add(new Models.MailReciever());
								}

								item.ListMailReciever[0].MailID = Convert.ToInt32(rd["MailID"]);
								item.ListMailReciever[0].Reciever = rd[rd.GetName(i)] == DBNull.Value ? string.Empty : Convert.ToString(rd[rd.GetName(i)]);
								item.ListMailReciever[0].IsDelete = Convert.ToInt32(rd["IsDelete"]);
								item.ListMailReciever[0].IsRead = Convert.ToInt32(rd["IsRead"]);
							}
							break;
					}
				}

				result = item;
			}

			return result;
		}

		#region IDisposable Members

		public void Dispose()
		{
			if(_KPIDbContext != null)
			{
				_KPIDbContext.Dispose();
			}
		}

		#endregion

		#region IMailRepository Members

		public bool CreateMail(Models.MailMessage theMailMessage)
		{
			var result = false;

			if(theMailMessage != null)
			{
				try
				{
					_KPIDbContext.MailMessages.Add(theMailMessage);

					result = (_KPIDbContext.SaveChanges() > 0);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public bool UpdateMail(Models.MailMessage theMailMessage)
		{
			var result = false;

			if(theMailMessage != null && theMailMessage.MailID > 0)
			{
				try
				{
					var theOrgMailMessage = _KPIDbContext.MailMessages.Find(theMailMessage.MailID);

					theMailMessage.MailSendTime = theOrgMailMessage.MailSendTime;

					if(theOrgMailMessage != null)
					{
						_KPIDbContext.Entry(theOrgMailMessage).CurrentValues.SetValues(theMailMessage);

						result = (_KPIDbContext.SaveChanges() > 0);
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public bool DeleteMail(int id)
		{
			var result = false;

			if(id > 0)
			{
				try
				{
					var theMailMessage = _KPIDbContext.MailMessages.Find(id);

					if(theMailMessage != null)
					{
						_KPIDbContext.MailMessages.Remove(theMailMessage);

						result = (_KPIDbContext.SaveChanges() > 0);
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public List<Models.MailMessage> GetRecievedMailList(string userName, int pageIndex, int pageSize, out int totalRecords)
		{
			List<Models.MailMessage> result = null;
			totalRecords = 0;

			System.Data.Common.DbDataReader rd = null;

			if(!string.IsNullOrWhiteSpace(userName))
			{
				try
				{
					_KPIDbContext.Database.Initialize(false);

					var cmd = _KPIDbContext.Database.Connection.CreateCommand();
					cmd.CommandText = "KPI_GetMail_Inbox";
					cmd.CommandType = System.Data.CommandType.StoredProcedure;

					System.Data.Common.DbParameter p1 = cmd.CreateParameter();
					p1.DbType = System.Data.DbType.String;
					p1.Direction = System.Data.ParameterDirection.Input;
					p1.ParameterName = "@RECIEVER";
					p1.Value = userName;
					System.Data.Common.DbParameter p2 = cmd.CreateParameter();
					p2.DbType = System.Data.DbType.Int32;
					p2.Direction = System.Data.ParameterDirection.Input;
					p2.ParameterName = "@PAGEINDEX";
					p2.Value = pageIndex;
					System.Data.Common.DbParameter p3 = cmd.CreateParameter();
					p3.DbType = System.Data.DbType.Int32;
					p3.Direction = System.Data.ParameterDirection.Input;
					p3.ParameterName = "@PAGESIZE";
					p3.Value = pageSize;
					System.Data.Common.DbParameter p4 = cmd.CreateParameter();
					p4.DbType = System.Data.DbType.Int32;
					p4.Direction = System.Data.ParameterDirection.InputOutput;
					p4.ParameterName = "@TOTALRECORDS";
					p4.Value = totalRecords;

					cmd.Parameters.Add(p1);
					cmd.Parameters.Add(p2);
					cmd.Parameters.Add(p3);
					cmd.Parameters.Add(p4);

					if(_KPIDbContext.Database.Connection.State != System.Data.ConnectionState.Open)
					{
						_KPIDbContext.Database.Connection.Open();
					}

					rd = cmd.ExecuteReader();

					while(rd.Read())
					{
						var item = GetMailMessageFromReader(rd);

						if(item != null)
						{
							if(result == null)
							{
								result = new List<Models.MailMessage>();
							}

							result.Add(item);
						}
					}

					if(!rd.IsClosed)
					{
						rd.Close();
					}

					totalRecords = Convert.ToInt32(cmd.Parameters["@TOTALRECORDS"].Value);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public List<Models.MailMessage> GetSentMailList(string userName, int pageIndex, int pageSize, out int totalRecords)
		{
			List<Models.MailMessage> result = null;
			totalRecords = 0;

			if(!string.IsNullOrWhiteSpace(userName))
			{
				try
				{
					totalRecords = _KPIDbContext.MailMessages.Count(m => m.MailIsDelete == 0 && m.MailFrom == userName);

					var mails = _KPIDbContext.MailMessages.Where(m => m.MailIsDelete == 0 && m.MailFrom == userName).OrderByDescending(m => m.MailSendTime).Skip((pageIndex - 1) * pageSize).Take(pageSize);

					if(mails != null)
					{
						result = mails.ToList();
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public Models.MailMessage GetTheMailMessage(int id)
		{
			Models.MailMessage result = null;

			if(id > 0)
			{
				try
				{
					result = _KPIDbContext.MailMessages.Include("ListMailReciever").FirstOrDefault(m => m.MailID == id);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public bool DeleteMail(List<int> ids)
		{
			var result = false;

			if(ids != null && ids.Count > 0)
			{
				try
				{
					foreach(var id in ids)
					{
						var mail = _KPIDbContext.MailMessages.Find(id);

						if(mail != null)
						{
							//_KPIDBContext.Task.Remove(task);
							mail.MailIsDelete = 1;
						}
					}

					if(_KPIDbContext.SaveChanges() > 0)
					{
						result = true;
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public bool DeleteOutboxMail(List<int> lstIDs)
		{
			var result = false;

			if(lstIDs != null && lstIDs.Count > 0)
			{
				try
				{
					foreach(var id in lstIDs)
					{
						var theMailMessage = _KPIDbContext.MailMessages.Find(id);

						if(theMailMessage != null)
						{
							theMailMessage.MailIsDelete = 1;
						}
					}

					result = (_KPIDbContext.SaveChanges() > 0);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public bool DeleteInboxMail(List<int> lstIDs, string reciever)
		{
			var result = false;

			if(!string.IsNullOrWhiteSpace(reciever) && lstIDs != null && lstIDs.Count > 0)
			{
				try
				{
					foreach(var id in lstIDs)
					{
						var theMailReciever = _KPIDbContext.MailRecievers.FirstOrDefault(mr => mr.MailID == id && mr.Reciever == reciever);

						if(theMailReciever != null)
						{
							theMailReciever.IsDelete = 1;
						}
					}

					result = (_KPIDbContext.SaveChanges() > 0);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public bool SetRecievedMailIsRead(string reciever, int mailID, int isRead)
		{
			var result = false;

			if(!string.IsNullOrWhiteSpace(reciever) && mailID > 0)
			{
				try
				{
					var theMailReciever = _KPIDbContext.MailRecievers.FirstOrDefault(mr => mr.MailID == mailID && mr.Reciever == reciever);

					if(theMailReciever != null)
					{
						theMailReciever.IsRead = isRead;

						result = (_KPIDbContext.SaveChanges() > 0);
					}
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		public int GetUnReadMailCount(string userName)
		{
			var result = 0;

			if(!string.IsNullOrWhiteSpace(userName))
			{
				try
				{
					result = _KPIDbContext.MailRecievers.Count(mr => mr.Reciever == userName && mr.IsRead == 0 && mr.IsDelete == 0);
				}
				catch
				{
					throw;
				}
			}

			return result;
		}

		#endregion
	}
}
